<template>
  <div class="folder-selector">
    <div v-loading="loading" class="folder-tree-container">
      <el-tree
        ref="treeRef"
        :data="folderTree"
        :props="treeProps"
        :default-expand-all="false"
        :expand-on-click-node="false"
        :check-on-click-node="true"
        :default-expanded-keys="expandedKeys"
        :current-node-key="selectedFolderId"
        @node-click="handleNodeClick"
        @node-expand="handleNodeExpand"
        node-key="id"
        class="folder-tree"
      >
        <template #default="{ node, data }">
          <div class="custom-tree-node">
            <el-icon class="folder-icon" :class="{ expanded: node.expanded }">
              <Folder />
            </el-icon>
            <span class="folder-name">{{ node.label }}</span>
            <span class="folder-path">{{ data.path }}</span>
          </div>
        </template>
      </el-tree>

      <!-- 空状态 -->
      <el-empty v-if="!loading && folderTree.length === 0" description="暂无文件夹" />
    </div>

    <!-- 当前选择的路径 -->
    <div v-if="selectedFolder" class="selected-path">
      <div class="path-label">当前选择:</div>
      <div class="path-breadcrumb">
        <el-breadcrumb separator="/">
          <el-breadcrumb-item v-for="item in pathBreadcrumb" :key="item.id">
            {{ item.name }}
          </el-breadcrumb-item>
        </el-breadcrumb>
      </div>
    </div>

    <!-- 操作按钮 -->
    <div class="selector-actions">
      <el-button @click="createNewFolder" :disabled="!canCreateFolder">
        <el-icon><FolderAdd /></el-icon>
        新建文件夹
      </el-button>
      <el-button @click="refreshTree">
        <el-icon><Refresh /></el-icon>
        刷新
      </el-button>
    </div>

    <!-- 新建文件夹对话框 -->
    <el-dialog v-model="showCreateDialog" title="新建文件夹" width="400px">
      <el-form :model="createForm" :rules="createRules" ref="createFormRef" label-width="80px">
        <el-form-item label="文件夹名" prop="name">
          <el-input
            v-model="createForm.name"
            placeholder="请输入文件夹名称"
            maxlength="50"
            show-word-limit
            @keyup.enter="confirmCreate"
          />
        </el-form-item>
        <el-form-item label="创建位置">
          <el-input
            :value="selectedFolder?.path || '/'"
            disabled
            placeholder="根目录"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="showCreateDialog = false">取消</el-button>
        <el-button type="primary" @click="confirmCreate" :loading="createLoading">
          确定
        </el-button>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, reactive, computed, watch, onMounted, nextTick } from 'vue'
import { ElMessage, type TreeInstance, type FormInstance, type FormRules } from 'element-plus'
import { Folder, FolderAdd, Refresh } from '@element-plus/icons-vue'
import { getFileList, createFolder, type FileInfo } from '@/api/file'

// Props 和 Emits
interface Props {
  modelValue?: number // 选中的文件夹ID
  excludeIds?: number[] // 排除的文件夹ID（防止循环引用）
  rootPath?: string // 根路径显示名称
}

interface Emits {
  (e: 'update:modelValue', value: number): void
  (e: 'change', folder: FolderNode | null): void
}

// 文件夹节点接口
interface FolderNode {
  id: number
  label: string
  path: string
  parentId: number
  children?: FolderNode[]
  isLeaf?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  modelValue: 0,
  excludeIds: () => [],
  rootPath: '根目录'
})

const emit = defineEmits<Emits>()

// 响应式数据
const loading = ref(false)
const createLoading = ref(false)
const showCreateDialog = ref(false)
const folderTree = ref<FolderNode[]>([])
const selectedFolderId = ref(0)
const expandedKeys = ref<number[]>([])

// 表单相关
const createFormRef = ref<FormInstance>()
const createForm = reactive({
  name: ''
})

const createRules: FormRules = {
  name: [
    { required: true, message: '请输入文件夹名称', trigger: 'blur' },
    { min: 1, max: 50, message: '文件夹名称长度为1-50个字符', trigger: 'blur' },
    {
      pattern: /^[^\/\\:*?"<>|]+$/,
      message: '文件夹名称不能包含特殊字符 \\ / : * ? " < > |',
      trigger: 'blur'
    }
  ]
}

// 树组件引用
const treeRef = ref<TreeInstance>()

// 树配置
const treeProps = {
  children: 'children',
  label: 'label',
  isLeaf: 'isLeaf'
}

// 计算属性
const selectedFolder = computed(() => {
  if (selectedFolderId.value === 0) {
    return {
      id: 0,
      label: props.rootPath,
      path: '/',
      parentId: -1
    }
  }
  return findNodeById(folderTree.value, selectedFolderId.value)
})

const pathBreadcrumb = computed(() => {
  if (!selectedFolder.value) return []

  const path: FolderNode[] = []
  let current: FolderNode | null = selectedFolder.value

  while (current) {
    path.unshift(current)
    if (current.parentId === -1) break
    current = findNodeById(folderTree.value, current.parentId) || null
  }

  return path.map(node => ({ id: node.id, name: node.label }))
})

const canCreateFolder = computed(() => {
  return selectedFolder.value !== null
})

// 监听选中状态变化
watch(() => props.modelValue, (newVal) => {
  selectedFolderId.value = newVal
})

watch(selectedFolderId, (newVal) => {
  emit('update:modelValue', newVal)
  emit('change', selectedFolder.value)
})

// 查找节点
const findNodeById = (nodes: FolderNode[], id: number): FolderNode | null => {
  for (const node of nodes) {
    if (node.id === id) return node
    if (node.children) {
      const found = findNodeById(node.children, id)
      if (found) return found
    }
  }
  return null
}

// 构建文件夹路径
const buildFolderPath = (files: FileInfo[], folderId: number): string => {
  if (folderId === 0) return '/'

  const folder = files.find(f => f.id === folderId)
  if (!folder) return '/'

  if (folder.parentId === 0) {
    return `/${folder.fileName}`
  }

  const parentPath = buildFolderPath(files, folder.parentId)
  return `${parentPath}/${folder.fileName}`
}

// 构建文件夹树
const buildFolderTree = (files: FileInfo[], parentId: number = 0): FolderNode[] => {
  const folders = files.filter(file =>
    file.isFolder === 1 &&
    file.parentId === parentId &&
    !props.excludeIds.includes(file.id)
  )

  return folders.map(folder => {
    const children = buildFolderTree(files, folder.id)
    return {
      id: folder.id,
      label: folder.fileName,
      path: buildFolderPath(files, folder.id),
      parentId: folder.parentId,
      children: children.length > 0 ? children : undefined,
      isLeaf: children.length === 0
    }
  })
}

// 递归获取所有文件夹
const getAllFolders = async (parentId: number = 0, allFolders: FileInfo[] = []): Promise<FileInfo[]> => {
  try {
    const response = await getFileList({
      parentId,
      page: 1,
      size: 1000,
      orderBy: 'fileName',
      orderType: 'asc'
    })

    const folders = response.content.filter(file =>
      file.isFolder === 1 && !props.excludeIds.includes(file.id)
    )
    allFolders.push(...folders)

    // 递归获取每个文件夹的子文件夹
    for (const folder of folders) {
      await getAllFolders(folder.id, allFolders)
    }

    return allFolders
  } catch (error) {
    console.error('获取文件夹失败:', error)
    return allFolders
  }
}

// 获取文件夹列表
const fetchFolderTree = async () => {
  try {
    loading.value = true

    // 获取所有文件夹
    const allFolders = await getAllFolders()

    // 构建完整的文件夹树
    const tree = buildFolderTree(allFolders)

    // 构建根目录节点
    const rootNode: FolderNode = {
      id: 0,
      label: props.rootPath,
      path: '/',
      parentId: -1,
      children: tree,
      isLeaf: false
    }

    folderTree.value = [rootNode]

    // 默认展开根目录
    const expandKeys = [0]
    // 展开第一级文件夹以便用户能看到更多选项
    if (tree.length > 0) {
      tree.forEach(node => {
        if (node.children && node.children.length > 0) {
          expandKeys.push(node.id)
        }
      })
    }
    expandedKeys.value = expandKeys

    // 设置初始选中
    if (props.modelValue !== undefined) {
      selectedFolderId.value = props.modelValue
    }

  } catch (error: any) {
    ElMessage.error(error.message || '获取文件夹列表失败')
  } finally {
    loading.value = false
  }
}

// 处理节点点击
const handleNodeClick = (data: FolderNode) => {
  selectedFolderId.value = data.id
}

// 处理节点展开（现在只是状态管理）
const handleNodeExpand = (data: FolderNode) => {
  // 由于现在是完整树结构，这里只需要处理展开状态
  // 可以在这里添加一些展开状态的逻辑，比如记录已展开的节点
}

// 新建文件夹
const createNewFolder = () => {
  createForm.name = ''
  showCreateDialog.value = true
  nextTick(() => {
    createFormRef.value?.resetFields()
  })
}

// 确认创建
const confirmCreate = async () => {
  if (!createFormRef.value) return

  try {
    const valid = await createFormRef.value.validate()
    if (!valid) return

    createLoading.value = true

    const parentId = selectedFolder.value?.id || 0
    const newFolder = await createFolder({
      folderName: createForm.name,
      parentId
    })

    ElMessage.success('文件夹创建成功')
    showCreateDialog.value = false

    // 刷新当前节点
    await refreshCurrentNode()

    // 自动选中新创建的文件夹
    selectedFolderId.value = newFolder.id

  } catch (error: any) {
    ElMessage.error(error.message || '创建文件夹失败')
  } finally {
    createLoading.value = false
  }
}

// 刷新当前节点
const refreshCurrentNode = async () => {
  if (selectedFolder.value) {
    const parentNode = findNodeById(folderTree.value, selectedFolder.value.parentId)
    if (parentNode && parentNode.children) {
      parentNode.children = []
      await handleNodeExpand(parentNode)
    }
  }
}

// 刷新整个树
const refreshTree = () => {
  fetchFolderTree()
}

// 初始化
onMounted(() => {
  fetchFolderTree()
})
</script>

<style scoped>
.folder-selector {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.folder-tree-container {
  flex: 1;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
  padding: 10px;
  overflow: auto;
  max-height: 400px;
  min-height: 200px;
}

.folder-tree {
  width: 100%;
}

.custom-tree-node {
  display: flex;
  align-items: center;
  gap: 8px;
  width: 100%;
  padding: 4px 0;
}

.folder-icon {
  color: #409eff;
  transition: transform 0.3s;
}

.folder-icon.expanded {
  transform: rotate(15deg);
}

.folder-name {
  font-weight: 500;
  color: #333;
}

.folder-path {
  font-size: 12px;
  color: #999;
  margin-left: auto;
}

.selected-path {
  margin: 15px 0;
  padding: 10px;
  background: #f8f9fa;
  border-radius: 4px;
}

.path-label {
  font-size: 12px;
  color: #666;
  margin-bottom: 5px;
}

.path-breadcrumb {
  font-size: 14px;
}

.selector-actions {
  display: flex;
  gap: 10px;
  margin-top: 10px;
}

/* 树节点样式优化 */
:deep(.el-tree-node__content) {
  height: auto;
  padding: 4px 8px;
}

:deep(.el-tree-node__content:hover) {
  background-color: #f0f9ff;
}

:deep(.el-tree-node.is-current > .el-tree-node__content) {
  background-color: #e1f5fe;
  color: #409eff;
}

:deep(.el-tree-node__expand-icon) {
  color: #999;
}

:deep(.el-tree-node__expand-icon.expanded) {
  transform: rotate(90deg);
}

/* 响应式设计 */
@media (max-width: 768px) {
  .folder-tree-container {
    max-height: 300px;
  }

  .selector-actions {
    flex-direction: column;
  }

  .custom-tree-node {
    flex-direction: column;
    align-items: flex-start;
    gap: 4px;
  }

  .folder-path {
    margin-left: 0;
    align-self: flex-start;
  }
}
</style>